/** 3DGPL *************************************************\
 *  (NeXTStep, 8bit deep bitmaps, 32bit mashine)          *
 *  Header for hardware specific stuff.                   *
 *                                                        *
 *  Defines:                                              *
 *    HW_open_screen         opening output surface;      *
 *    HW_blit                colourmap onto the screen;   *
 *    HW_close_screen        closing output;              *
 *                                                        *
 *    HW_run_event_loop      runiing for events;          *
 *    HW_quit_event_loop     quiting running.             *
 *                                                        *
 *  (6/1995) By Sergei Savhenko. (savs@cs.mcgill.ca).     *
 *  Copyright (c) 1995 Sergei Savchenko.                  *
 *  THIS SOURCE CODE CAN'T BE USED FOR COMERCIAL PURPOSES *
 *  WITHOUT AUTHORISATION                                 *
\**********************************************************/
 
#import  <appkit/appkit.h>                  /* id type */
#import  <dpsclient/wraps.h>                /* DPS functions */
#import  <dpsclient/event.h>                /* Event mascks */
#include "../hardware/hardware.h"           /* harware dependent stuff */

id HW_window;                               /* application's main window */
id HW_view;                                 /* the "view" of the window */
NXRect HW_rect;                             /* screen boundaries */
DPSTimedEntry HW_entry;                     /* initialized timed entry */

unsigned char *HW_colourmap;                /* where drwaings go to */

void (*HW_application_main)(void);
void (*HW_application_key_handler)(int key_code);

/**********************************************************\
 *  Implementations for fast memory operations.           *
\**********************************************************/
				  
void HW_set_int(int *d,long l,int v) {long i; for(i=0;i<l;i++) *d++=v; }

/**********************************************************\
 * Creating a window.                                     *
 * RETURNS:  0 on display opening error;                  *
 * --------  1 on success.                                *
\**********************************************************/

int HW_open_screen(char *display_name,char *screen_name,
		   struct HW_colour palette[256],unsigned char *colourmap
		  )
{
 [Application new];

 HW_colourmap=colourmap;

 NXSetRect(&HW_rect,360.0,300.0,HW_SCREEN_X_SIZE,HW_SCREEN_Y_SIZE);
 HW_window = [[Window alloc] initContent:&HW_rect
				   style:NX_TITLEDSTYLE
				 backing:NX_BUFFERED
			      buttonMask:NX_MINIATURIZEBUTTONMASK
				   defer:NO];

 [HW_window setTitle:screen_name];
 [HW_window display];
 [HW_window orderFront:nil];

 HW_view=[HW_window contentView];            /* window's main view */
 NXSetRect(&HW_rect,0.0,0.0,HW_SCREEN_X_SIZE,HW_SCREEN_Y_SIZE);
 [HW_view allocateGState];
}

/**********************************************************\
 * blitting a bitmap into the allocated window.           *
\**********************************************************/

void HW_blit(void)
{
 [HW_view lockFocus];                       /* lock output on the view */

 NXImageBitmap(&HW_rect,HW_SCREEN_X_SIZE,HW_SCREEN_Y_SIZE,8,1,NX_MESHED,
	       NX_MONOTONICMASK,HW_colourmap,NULL,NULL,NULL,NULL
	      );

 [HW_window flushWindow];                   /* image appears on screen */
 [HW_view unlockFocus];                     /* unlock output */
}

/**********************************************************\
 * Deallocating a window.                                 *
\**********************************************************/

void HW_close_screen(void)
{
}

/**********************************************************\
 * The main event loop.                                   *
\**********************************************************/

void HW_event_loop()
{
 NXEvent *anEvent;

 HW_application_main();

 while((anEvent=[NXApp getNextEvent:NX_KEYDOWNMASK   
			 waitFor:0.0
		       threshold:NX_BASETHRESHOLD])!=NULL)
  HW_application_key_handler(anEvent->data.key.charCode);
}

/**********************************************************\
 * running the event loop.                                *
\**********************************************************/

void HW_run_event_loop(void (*application_main)(void),
		       void (*application_key_handler)(int key_code)
		      )
{
 [HW_window makeKeyWindow];
 
 HW_application_main=application_main;
 HW_application_key_handler=application_key_handler;
 HW_entry=DPSAddTimedEntry(0.0,&HW_event_loop,NULL,NX_BASETHRESHOLD);

 [NXApp run];
 [NXApp free];
}

/**********************************************************\
 *  quiting the event loop.                               *
\**********************************************************/

void HW_quit_event_loop(void)
{
 DPSRemoveTimedEntry(HW_entry);
 [NXApp terminate:0];   
}

/**********************************************************/
